
/*
回溯
连接：https://leetcode.cn/problems/target-sum/description/
题目：494. 目标和


    3. 解法（回溯）：
    算法思路：
    对于每个数，可以选择加上或减去它，依次枚举每⼀个数字，在每个数都被选择时检查得到的和是否
    等于⽬标值。如果等于，则记录结果。
    需要注意的是，为了优化时间复杂度，可以提前计算出数组中所有数字的和 sum，以及数组的⻓度
    len。这样可以快速判断当前的和减去剩余的所有数是否已经超过了⽬标值 target ，或者当前的和加上
    剩下的数的和是否⼩于⽬标值 target，如果满⾜条件，则可以直接回溯。
    递归流程：
    1. 递归结束条件：index 与数组⻓度相等，判断当前状态的 sum 是否与⽬标值相等，若是计数加⼀；
    2. 选择当前元素进⾏加操作，递归下⼀个位置，并更新参数 sum；
    3. 选择当前元素进⾏减操作，递归下⼀个位置，并更新参数 sum；
    • 特别地，此问题可以转化为另⼀个问题：若所有元素初始状态均为减，选择其中⼏个元素将他们的
    状态修改为加，计算修改后的元素和与⽬标值相等的⽅案个数。
    1. 选择其中 x 个元素进⾏修改，并且这 x 个元素的和为 y；
    2. 检查使得 -sum+2*y=target（移项：y=(sum+target)/2）成⽴的⽅案个数，即选择 x 个元素和为
    (sum+target)/2 的⽅案个数；
    a. 若 sum+target 为奇数，则不存在这种⽅案；
    3. 递归流程：
    a. 传⼊参数：index（当前要处理的元素下标），sum（当前状态和），nums（元素数组），
    aim（⽬标值：(sum+target)/2）；
    b. 递归结束条件：index 与数组⻓度相等，判断当前 sum 是否与⽬标值相等，若是返回 1，否则
    返回 0；
    c. 返回 递归选择当前元素 以及 递归不选择当前元素 函数值的和。

*/
class Solution {
public:
    int ret=0;
    int target;
    int findTargetSumWays(vector<int>& nums, int _target) {
       target = _target;
       dfs(nums,0,0);
       return ret;
    }
    void dfs(vector<int>& nums,int sum,int pos)
    {
        if(pos==nums.size())
        {
            if(sum == target)
            {
                ret++;
            }
            return ;
        }
        dfs(nums,sum+nums[pos],pos+1);
        dfs(nums,sum-nums[pos],pos+1);
    }
};